//
//	File: RenderBatch.h
//
#ifndef OY_RENDERBATCH_H
#define OY_RENDERBATCH_H

#include "../../OyMath3D/OyMath3D.h"
#include "../DataStruct/OyDataStruct.h"
#include <Windows.h>

class OyD3D9StaticBuffer;
class OyD3D9VertexCache;
class OyD3D9SkinManager;
class OyDirect3D9;

// RenderBatch Base virtual class
class CRenderBatch
{
public:
	enum BatchType
	{
		eBatchOpaque = 0,
		eBatchOpaqueAlphaTest,
		eBatchTransparent,

		eBatchNumMax,
	};

	CRenderBatch() { m_pSB = 0; m_pVC = 0; m_BatchType = eBatchNumMax; m_MatWorld.Identity(); }
	virtual ~CRenderBatch() { }

	virtual void		BuildQueueValue() = 0;
	virtual ULONG64		GetQueueValue() = 0;
	virtual void		Render();
	virtual void		PreRender();
	virtual void		PostRender();

	BatchType			GetBatchType() { return m_BatchType; }

public:
	BatchType			m_BatchType;
	OyVector4D			m_BBOXCenter;
	OyMatrix			m_MatWorld;
	OyD3D9StaticBuffer* m_pSB;
	OyD3D9VertexCache*	m_pVC;
};


class COpaqueRenderBatch : public CRenderBatch
{
public:
	COpaqueRenderBatch() { m_BatchType = eBatchOpaque; }

	virtual void BuildQueueValue();
	virtual ULONG64	GetQueueValue()	{ return stQueueValue.ulQueueValue; }

	union
	{
		struct
		{
			ULONG64 ulReserved				: 4;    // unused bits
			ULONG64 uldistance				: 32;	// object distance from camera
			ULONG64 ulshader				: 12;	// 12 bits for shader (0-4096)
			ULONG64 ulpriority				: 6;    // 6 bits for user given priority (0-64)
			ULONG64 ulqueue_id				: 10;	// 10 bits for user given queue (0-1024)
		};
		ULONG64 ulQueueValue;
	} stQueueValue;
};

class COpaqueAlphaTestRenderBatch : public CRenderBatch
{
public:
	COpaqueAlphaTestRenderBatch() { m_BatchType = eBatchOpaqueAlphaTest; }

	virtual void BuildQueueValue();
	virtual ULONG64	GetQueueValue()	{ return stQueueValue.ulQueueValue; }

	union
	{
		struct
		{
			ULONG64 ulReserved				: 4;    // unused bits
			ULONG64 uldistance				: 32;	// object distance from camera
			ULONG64 ulshader				: 12;	// 12 bits for shader (0-4096)
			ULONG64 ulpriority				: 6;    // 6 bits for user given priority (0-64)
			ULONG64 ulqueue_id				: 10;	// 10 bits for user given queue (0-1024)
		};
		ULONG64 ulQueueValue;
	} stQueueValue;
};

class CTransparentRenderBatch : public CRenderBatch
{
public:
	CTransparentRenderBatch() { m_BatchType = eBatchTransparent; }

	virtual void BuildQueueValue();
	virtual ULONG64	GetQueueValue()	{ return stQueueValue.ulQueueValue; }

	union
	{
		struct
		{
			ULONG64 ulReserved				: 4;    // unused bits
			ULONG64 ulshader				: 12;	// 12 bits for shader (0-4096)
			ULONG64 ulpriority				: 6;    // 6 bits for user given priority (0-64)
			ULONG64 uldistance				: 32;	// object distance from camera
			ULONG64 ulqueue_id				: 10;	// 10 bits for user given queue (0-1024)
		};
		ULONG64 ulQueueValue;
	} stQueueValue;
};

typedef OyArrayStack<COpaqueRenderBatch*>			OpaqueRenderBatchVector;
typedef OyArrayStack<COpaqueAlphaTestRenderBatch*>	OpaqueAlphaTestRenderBatchVector;
typedef OyArrayStack<CTransparentRenderBatch*>		TransparentRenderBatchVector;

#endif